# encoding: utf-8
require 'terminal-table'

class RateCLI

  module Helper

    def ask_dir(question)
      path = nil
      loop do
        path = @sui.ask question
        if not File.directory?(path)
          error "No such directory: #{path}"
        else
          break
        end
      end
    end

    def ask_file(question)
      path = nil
      loop do
        path = @sui.ask question
        if File.directory?(path)
          error "File path required, but you give a directory"
        elsif not File.exists?(path)
          error "No such file: #{path}"
        else
          break
        end
      end
      path
    end

    def choose_list(question, list)
      loop do
        option, index = @sui.choose_from_list(question, list)
        if index >= 0 && index < list.size
          return option
        end
      end
    end

    def choose_from_harray(question, harray, header)
      page = 1
      total_page = (harray.size / Float(@per_page) + 0.5).round

      content_for_page = lambda do
        page = [page, 1].max
        page = [page, total_page].min
        skip = (page-1)*@per_page
        harray[skip...(skip+@per_page)]
      end

      id2global = lambda do |id|
        (page-1)*@per_page + id
      end

      loop do
        puts question

        contents = content_for_page.call
        puts harray2table(contents, header)
        puts "#{page}/#{total_page}"

        number = @sui.ask "Which? (< >)"
        case number
        when '<' then page -= 1
        when '>' then page += 1
        when /\d/
          number = number.to_i
          gnumber = id2global.call(number)
          return number if gnumber <= harray.size && gnumber >= 1
        end
      end

    end

    def print_options(options)
      options.each do |k, v|
        if v.is_a?(Hash)
          puts "%20s\t%s" % [k, "#{v['name']} [#{short_uuid(v['uuid'])}]"]
        else
          puts "%20s\t%s" % [k, v]
        end
      end
    end


    def fatal(msg, bold=false)
      if bold
        puts Rainbow(msg).red.bright
      else
        puts Rainbow(msg).red
      end
    end

    def success(msg, bold=false)
      if bold
        puts Rainbow(msg).green.bright
      else
        puts Rainbow(msg).green
      end
    end

    def error(msg, bold=false)
      if bold
        puts Rainbow(msg).yellow.bright
      else
        puts Rainbow(msg).yellow
      end
    end

    def info(msg,bold=false)
      if bold
        puts Rainbow(msg).blue.bright
      else
        puts Rainbow(msg).blue
      end
    end

    def hash2table(h)
      table = Terminal::Table.new do |t|
        h.each do |k, v|
          k = k.to_s
          if v
            if k.end_with?('uuid') && k != 'uuid'
              info = _get_info_by_uuid(k, v, h)
              h2 = translate_headers([k]).first
              t << [h2, info]
            else
              t << [k.to_s, v.to_s]
            end
          else
            t << [k.to_s, '']
          end
        end
      end

      table
    end

    def _get_info_by_uuid(target, uuid, entity)
      case target
      when 'auuid' then target = 'algorithm'
      when 'buuid' then target = 'benchmark'
      when 'uuid' then return short_uuid(uuid)
      when 'view_uuid' then target = 'view'
      when 'user_uuid' then target = 'user'
      end

      return "%s [%s]" % [short_uuid(uuid), entity["#{target}_name"]]
    end

    def translate_headers(headers)
      headers.map do |header|
        case header
        when 'auuid' then 'algorithm'
        when 'buuid' then 'benchmark'
        when 'view_uuid' then 'view'
        when 'user_uuid' then 'user'
        else header
        end
      end
    end

    def get_pbar(progress, length=10)
      bar = ""
      bar << '['
      passed = progress * (length-1)
      remain = length - passed - 1
      bar << "=" * passed
      bar << ">" if progress < 1.0 
      bar << " " * remain
      bar << "] %2.2f%" % [progress * 100]

      bar
    end

    def harray2table(harray, headers)
      table = Terminal::Table.new do |t|
        t.headings = ['No.'] + translate_headers(headers)
        i = 1
        harray.each_with_index do |h, index|
          row = [i.to_s]
          headers.each do |header|
            if h[header]
              if header.end_with?('uuid')
                row << _get_info_by_uuid(header, h[header], h)
              elsif header == 'progress'
                row << get_pbar(h[header])
              elsif header == 'name'
                row << h[header].to_s[0...15].bright
              elsif header == 'description'
                row << multiline(h[header])
              else
                row << h[header]
              end
            else
              row << ''
            end
          end
          t << row
          if index < harray.size - 1
            t << :separator
          end
          i += 1
        end
      end

      table
    end

    def multiline(str, perline=20)
      nline = (str.length / Float(perline) + 0.5).round
      newstr = ""
      (1..nline).each do |n|
        skip = (n-1)*perline
        newstr << str[skip...(skip+perline)] << "\n"
      end

      newstr
    end

    def short_uuid(uuid)
      uuid.split('-')[0]
    end

    def humanize(str)
      str.capitalize
    end

    def humanplural(str)
      str.capitalize + 's'
    end
  end
end
